package cplus_cplus_std

import (
	"errors"
)

// UnorderedMap 泛型映射容器，类似C++的unordered_map
type UnorderedMap[K comparable, V any] struct {
	data map[K]V
}

// New 创建一个新的UnorderedMap
func MakeMaprObj[K comparable, V any]() *UnorderedMap[K, V] {
	return &UnorderedMap[K, V]{
		data: make(map[K]V),
	}
}

// NewWithCapacity 创建带初始容量的UnorderedMap
func NewWithCapacity[K comparable, V any](capacity int) *UnorderedMap[K, V] {
	return &UnorderedMap[K, V]{
		data: make(map[K]V, capacity),
	}
}

// Size 返回元素数量
func (m *UnorderedMap[K, V]) Size() int {
	return len(m.data)
}

// Empty 判断是否为空
func (m *UnorderedMap[K, V]) Empty() bool {
	return len(m.data) == 0
}

// Clear 清空所有元素
func (m *UnorderedMap[K, V]) Clear() {
	m.data = make(map[K]V) // 创建新map，帮助GC
}

// Insert 插入或更新键值对
func (m *UnorderedMap[K, V]) Insert(key K, value V) {
	m.data[key] = value
}

// Emplace 插入元素（如果键不存在）
func (m *UnorderedMap[K, V]) Emplace(key K, value V) bool {
	if _, exists := m.data[key]; exists {
		return false // 键已存在
	}
	m.data[key] = value
	return true
}

// At 获取指定键的值，不存在时返回错误
func (m *UnorderedMap[K, V]) At(key K) (V, error) {
	var zero V
	value, exists := m.data[key]
	if !exists {
		return zero, errors.New("key not found")
	}
	return value, nil
}

// AtOrDefault 获取指定键的值，不存在时返回默认值
func (m *UnorderedMap[K, V]) AtOrDefault(key K, defaultValue V) V {
	if value, exists := m.data[key]; exists {
		return value
	}
	return defaultValue
}

// Erase 删除指定键的元素
func (m *UnorderedMap[K, V]) Erase(key K) bool {
	if _, exists := m.data[key]; !exists {
		return false // 键不存在
	}
	delete(m.data, key)
	return true
}

// Count 返回指定键的元素数量（0或1）
func (m *UnorderedMap[K, V]) Count(key K) int {
	if _, exists := m.data[key]; exists {
		return 1
	}
	return 0
}

// Find 查找键是否存在
func (m *UnorderedMap[K, V]) Find(key K) (V, bool) {
	value, exists := m.data[key]
	return value, exists
}

// Keys 返回所有键的切片
func (m *UnorderedMap[K, V]) Keys() []K {
	keys := make([]K, 0, len(m.data))
	for k := range m.data {
		keys = append(keys, k)
	}
	return keys
}

// Values 返回所有值的切片
func (m *UnorderedMap[K, V]) Values() []V {
	values := make([]V, 0, len(m.data))
	for _, v := range m.data {
		values = append(values, v)
	}
	return values
}

// ForEach 遍历所有元素
func (m *UnorderedMap[K, V]) ForEach(fn func(key K, value V) bool) {
	for k, v := range m.data {
		if !fn(k, v) {
			break // 如果回调返回false，则终止遍历
		}
	}
}
